/*
	公共JS
*/
$(function(){	
	// 处理登录页面 密码眼睛问题
	$(".eye").on("click", function(){
		if ($(this).hasClass("clos")) {
			$(this).removeClass("clos").addClass("open")
			$("input.pass").attr("type", "text")
		}else{
			$(this).removeClass("open").addClass("clos")
			$("input.pass").attr("type", "password")
		}
	})
	
})


Date.prototype.format = function(pattern) {
	// 获取年份 , this 代表日期对象
	let year = this.getFullYear() ;
	// month  0-11
	let month = this.getMonth() + 1 < 10 ? "0" + (this.getMonth() + 1) :this.getMonth() + 1 ;
	// 获取天
	let day = this.getDate() < 10 ? "0"+ this.getDate() : this.getDate() ;

	let hour = this.getHours() < 10 ? "0" + this.getHours() : this.getHours();

	let min = this.getMinutes() < 10 ? "0" + this.getMinutes(): this.getMinutes();

	let sec = this.getSeconds() < 10 ? "0" + this.getSeconds(): this.getSeconds();

	let millsec = this.getMilliseconds() ;
	// 获取 星期
	let week = this.getDay() ;

	let weekday = ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"]
	let engweek = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]

	return pattern.replace("yyyy", year)
		.replace("MM", month)
		.replace("dd", day)
		.replace("HH", hour)
		.replace("mm", min)
		.replace("ss", sec)
		.replace("SSS", millsec)
		.replace("E", weekday[week])
		.replace("e", engweek[week])
}


/**
 * 获取任意元素距离浏览器的距离
 */
Element.prototype.getClientPos = function(){
	let left = 0, top = 0 , ele = this ;;
	while(ele.offsetParent) {
		left += ele.offsetLeft ;
		top += ele.offsetTop ;
		ele = ele.offsetParent ;
	}
	return {left: left, top: top}
}

/**
 * 随机产生一个颜色
 */
function ramdomColor() {
	let x = Math.floor(Math.random() * 256) ;
	let y = Math.floor(Math.random() * 256) ;
	let z = Math.floor(Math.random() * 256) ;
	return `rgb(${x}, ${y}, ${z})`
}


/**
 *  position 如果不传， 放大镜默认在图片的右侧出现，
 * 	position 支持的值 left
 */
HTMLImageElement.prototype.zoom = function(position) {
	// this 代表 img 元素
	// 获取目标图片元素的大小
	let width = this.clientWidth ;
	let height = this.clientHeight ;
	// 获取宽高的最小值
	let min = Math.min(width, height) ;
	let wh = Math.floor(min/2)

	// 为了在事件中操作图片
	let imgTag = this ;
	// 获取图片的父级元素
	let parentNode = this.offsetParent ;

	// 定义两个需要创建的元素对象
	let divTag = false , large = false ;
	// 给图片绑定一个 mouseenter 事件，
	this.addEventListener("mouseenter", function(event) {
		// 给 img 添加遮罩层, 并使用绝对定位
		// 遮罩层永远相对于 img 的 父级的定位
		divTag = document.createElement("div") ;
		// 遮罩层的宽高 取 min的一半
		divTag.style.width = wh + "px" ;
		divTag.style.height = wh + "px" ;
		// 设置遮罩层的背景颜色
		divTag.style.backgroundColor = "rgba(255,255,0,0.3)"

		// 设置 遮罩层的定位方式 绝对定位
		divTag.style.position = "absolute" ;

		// 遮罩层 left 值 和 top 值,取决与 img 相对于父级元素的位置
		divTag.style.left = this.offsetLeft + "px" ;
		divTag.style.top = this.offsetTop + "px" ;

		// 给遮罩层设置一个鼠标样式为 move
		divTag.style.cursor = "move" ;

		// 将divTag 追加到 img标签的父级元素下
		this.parentNode.appendChild(divTag);

		// 创建一个DIV元素, 出现在 图片的右边
		large = document.createElement("div") ;
		// 设置定位
		large.style.position = "absolute" ;
		// 设置背景图
		large.style.backgroundImage = `url(${this.src})` ;

		// 将 large 和 图片平行
		large.style.left = this.offsetLeft + this.offsetWidth + "px" ;
		large.style.top = this.offsetTop + "px" ;
		// 将large追加到 img的父级元素下
		this.parentNode.appendChild(large);

		// 绑定鼠标离开事件，用来删除 生成的遮罩层和放大的区域元素
		divTag.addEventListener("mouseleave", function(event) {
			if (divTag) divTag.remove();
			if (large) large.remove();
		})

	})


	// 给 目标图片,绑定 鼠标移动事件
	document.addEventListener("mousemove", function(event){
		// 判断鼠标在是否在遮罩层上
		if(event.target !== divTag && event.target != imgTag) return ;

		// 获取 鼠标相对于浏览器的位置 pageX, pageY
		let pageX = event.pageX ;
		let pageY = event.pageY ;

		// 遮罩层跟随鼠标出现的位置
		// 鼠标距离浏览器的距离 - img具有定位元素的父亲 到浏览器的记录 - 遮罩层的 1/2
		// 获取图片父级元素距离浏览器的偏移量
		let pos = parentNode.getClientPos();
		let left = pageX - pos.left - wh/2 ;
		let top = pageY - pos.top - wh/2 ;

		// 判断 遮罩层 是否超出了上边界
		if (imgTag.offsetTop >= top) {
			top = imgTag.offsetTop ;
		}
		// 判断是否超出了下边界
		if (top >= imgTag.offsetTop + imgTag.clientHeight - divTag.offsetHeight) {
			top = imgTag.offsetTop + imgTag.clientHeight - divTag.offsetHeight ;
		}

		// 判断是否超出了 左边界
		if(left <= imgTag.offsetLeft) {
			left = imgTag.offsetLeft
		}
		// 判断是否超出了 右边界
		if (left >= imgTag.offsetLeft + imgTag.clientWidth - divTag.offsetWidth) {
			left = imgTag.offsetLeft + imgTag.clientWidth - divTag.offsetWidth ;
		}
		// 将遮罩层, 固定到 图片所在的区域中
		divTag.style.left = left + "px" ;
		divTag.style.top = top + "px" ;

		// 计算遮罩层中心点 在图片中的位置
		let cx = divTag.offsetLeft - imgTag.offsetLeft + wh/2 ;
		let cy = divTag.offsetTop - imgTag.offsetTop + wh / 2;

		// 获取图片的原始宽高
		let img = new Image() ;
		img.src = imgTag.src ;

		// 加载图片是需要时间的,所以需要监听图片是否加载完成
		// onload 代表图片加载完成
		img.onload = function() {
			// 获取图片的真实宽高
			// 获取放大后的 X, Y
			let x = cx / imgTag.clientWidth * img.width ;
			let y = cy / imgTag.clientHeight * img.height ;
			// 获取 中心点到 放大图片边 的距离
			let lengthX = wh/2 / imgTag.clientWidth * img.width  ;
			let lengthY = wh/2 / imgTag.clientHeight * img.height ;

			// 计算 图片的切图位置
			let px = x -lengthX ;
			let py = y -lengthY ;

			large.style.width = lengthX * 2 + "px";
			large.style.height = lengthY * 2 + "px";

			if (position === "left") {
				large.style.left =  this.offsetLeft - (lengthX * 2)  + "px" ;
			}

			// 使用 backgroundPosition 定位图片
			large.style.backgroundPosition = `-${px}px -${py}px` ;
		}
	})
}

function uuid() {
	function S4() {
		return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
	}
	return (S4() + S4() + "-" + S4() + "-" + S4() + "-" + S4() + "-" + S4() + S4() + S4());
}

/**
 * 操作提示框
 */
$.extend({
	showMsg({msg, icon="info", duration=2000} = {}) {
		// 调用 uuid 生成唯一的 ID 编号
		//console.log(this.uuid())
		let uuids = uuid() ;

		let showMsgHtml = `
			<div id="show-msg-${uuids}">
				<div class="title">
					<b>消息提示信息</b>
					<a class="close">X</a>
				</div>
				<div class="content">
					<div>${msg}</div>
				</div>
			</div>
		`
		let tag = $(showMsgHtml) ;
		tag.css({
			position: "fixed",
			width: "260px",
			height:"160px",
			bottom: "0",
			right: "2px",
			border:"1px solid #999",
			display: "none",
			zIndex: 999,
			userSelect: "none"
		}).find(".title").css({
			position: "relative",
			height: "40px",
			paddingLeft: "40px",
			lineHeight: "40px",
			fontSize:"20px",
			color:"#fff",
			backgroundColor: "#FF009F",
			//background: `#FF009F url(./images/${icon}.png) no-repeat 5px center /30px 30px`
		}).addClass(icon).find(".close").css({
			position: "absolute",
			display: "block",
			width: "40px",
			height:"40px",
			top: "0 ",
			right:"0px",
			textAlign: "center",
			lineHeight: "40px",
			fontSize:"20px",
			cursor: "pointer"
		})

		tag.find(".content").css({
			padding: "30px 20px",
			fontSize: "20px",
			height:"60px"
		}).find("div").css("overflow", "hidden")

		// 将内容添加到 body中
		$(document.body).append(tag)

		tag.stop(true, true).slideDown() ;
		// 消息框，进入时添加 滑入动画

		// 给 X 绑定单击事件，实现关闭效果
		tag.find(".close").on("click", function(event){
			tag.stop(true, true).slideUp(function(){
				// 移除该元素
				tag.remove();
			}) ;
		})
		// 添加一个延迟方法，  延迟指定的事件后， 自动关闭窗口
		setTimeout(function(){
			// 模拟手动触发 X 单击事件，自动调用X的单击事件
			tag.find(".close").trigger("click")
		} , duration)
	},

	info(msg, duration) {
		this.showMsg({msg, icon: "info", duration})
	},
	warn(msg, duration) {
		this.showMsg({msg, icon: "warn", duration})
	},
	error(msg, duration) {
		this.showMsg({msg, icon: "error", duration})
	}

})

/**
 * 表单错误信息 提示框
 */
$.fn.extend({

	tooltips(msg, timeout=2000) {
		// 如果 目标元素选中了多个元素，则抛出错误
		if (this.length > 1) {
			throw new Error("tooltips方法期待处理的元素个数为1，实际选中了" + this.length + "个元素")
		}
		let uuids = uuid() ;
		let tag = $(`<span id="tooltips-${uuids}">${msg}</span>`) ;
		// 设置 提示框的基本样式
		tag.css({
			position: "absolute",
			fontSize: "10px",
			background: "rgba(0,0,0, 0.9)",
			color: "#fff",
			padding:"3px 10px",
			zIndex: 999 ,
		}).insertAfter(this)

		// 获取 目标元素相当于 具有定位的父级元素的位置
		let {left, top} = this.position();

		// 获取 目标元素的宽度
		let target_width = this.outerWidth() ;

		// 获取 提示框的 宽高
		let width = tag.innerWidth() ;
		let height = tag.innerHeight() ;

		// 移动提示框，到目标元素上方中心位置
		tag.css({
			left: target_width/2 + left - width/2 + "px",
			top: top - height -2 + "px" ,
		})
		// 在指定时间后，关闭提示框
		setTimeout(function(){
			tag.stop(true, true).fadeOut(function(){
				tag.remove();
			})
		}, timeout)
	}
}) ;


/**
 * 将 ES6 中的 fetch 进行封装 ，优化代码的使用
 *
 */

(function(){
	// 获取 fetch 函数
	let originFetch = window.fetch ;
	// 覆盖掉 原生 fetch
	window.fetch = function(url, options = {}) {

		// 获取 headers 头信息
		let headers = options.headers !=null ? options.headers : {} ;
		// 用来标记当前请求是异步请求
		headers["x-requested-with"] = "XMLHttpRequest"  ;
		options.headers = headers ;

		return originFetch(url, options).then(response => {
			if (response.status >= 200 && response.status < 300 || response.status === 304) {
				return response.json()
			}

			// 如果 没有成功， 服务器接口产生异常
			let error = new Error("接口异常") ;
			error.response = response ;
			throw error ;
		}).catch(error => {
			// 判断 状态码 ，如果 是 401 代表 没有登录
			if (error.response.status === 401) {
				console.log(error.response)

				error.response.json().then(ret => {
					// 获取到 登录的地址
					window.location.href = ret.data.loginUrl ;
				})
			}
			throw new Error(error.message);
		});

	}
})()